import uvm_pkg::*;
`include "uvm_macros.svh"

class spt_rx_monitor extends uvm_monitor;
	`uvm_component_utils(spt_rx_monitor)
	uvm_analysis_port #(spt_packet) out_port;
	spt_packet mon_rx_tr;
	virtual spt_interface vif;
	
	extern function new(string name,uvm_component parent);
	extern virtual function void build_phase(uvm_phase phase);
	extern virtual task run_phase(uvm_phase phase);
	extern virtual task sample_rx_data();
endclass:spt_rx_monitor

function spt_rx_monitor::new(string name,uvm_component parent);
super.new(name,parent);
this.out_port=new("out_port",this);
`uvm_info(get_type_name(),"new():spt_rx_monitor has been constructed",UVM_HIGH);
endfunction:new

function void spt_rx_monitor::build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual spt_interface)::get(this,"","vif",this.vif))begin
  `uvm_error(get_type_name(),"build_phase():Virtual interface in monitor is not configured");
end
endfunction:build_phase

task spt_rx_monitor::run_phase(uvm_phase phase);
super.run_phase(phase);
this.sample_rx_data();
endtask:run_phase

task spt_rx_monitor::sample_rx_data();
bit[15:0]sample_data[$];
bit    vld_before;
this.mon_rx_tr=spt_packet::type_id::create("mon_rx_tr",this);

@(posedge vif.rst_n)
 while(1) begin
    @(posedge vif.clk)
	if(vif.vld_out==1'b1)begin
      sample_data.push_back(vif.data_out);
    end
    else if(vif.vld_out==1'b0 && vld_before==1'b1)begin
       mon_rx_tr.pkt_data=new[sample_data.size];
       foreach(sample_data[i])begin;
          mon_rx_tr.pkt_data[i]=sample_data[i];
       end
       sample_data.delete();
       this.out_port.write(mon_rx_tr);
       `uvm_info(get_type_name(),$sformatf("sample_stimulus_data():Finish:%s",mon_rx_tr.sprint()),UVM_HIGH);
    end
    
	vld_before=vif.vld_out;
end
endtask:sample_rx_data
